package com.cencat.order.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.common.result.Result;
import com.cencat.order.entity.Order;
import com.cencat.order.service.OrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 订单控制器
 * 
 * @author cencat
 * @version 1.0
 * @since 2024-12-19
 */
@Tag(name = "订单管理", description = "订单相关接口")
@RestController
@RequestMapping("/api/order")
@CrossOrigin(origins = "*")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Operation(summary = "分页查询订单列表", description = "根据条件分页查询订单信息")
    @GetMapping("/page")
    public Result<IPage<Order>> getOrderPage(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "订单状态") @RequestParam(required = false) Integer orderStatus,
            @Parameter(description = "用户ID") @RequestParam(required = false) Long userId,
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        Page<Order> page = new Page<>(current, size);
        IPage<Order> result = orderService.getOrderPage(page, orderStatus, userId, driverId, startTime, endTime);
        return Result.success(result);
    }

    @Operation(summary = "根据ID获取订单详情", description = "根据订单ID获取详细信息")
    @GetMapping("/{id}")
    public Result<Order> getOrderById(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id) {
        
        Order order = orderService.getById(id);
        if (order == null) {
            return Result.error("订单不存在");
        }
        return Result.success(order);
    }

    @Operation(summary = "根据订单号获取订单", description = "根据订单号获取订单信息")
    @GetMapping("/code/{orderCode}")
    public Result<Order> getOrderByCode(
            @Parameter(description = "订单号", required = true) @PathVariable String orderCode) {
        
        Order order = orderService.getOrderByCode(orderCode);
        if (order == null) {
            return Result.error("订单不存在");
        }
        return Result.success(order);
    }

    @Operation(summary = "创建订单", description = "创建新的订单")
    @PostMapping
    public Result<Boolean> createOrder(
            @Parameter(description = "订单信息", required = true) @RequestBody @Valid Order order) {
        
        boolean result = orderService.createOrder(order);
        if (result) {
            return Result.success(true, "订单创建成功");
        }
        return Result.error("订单创建失败");
    }

    @Operation(summary = "更新订单状态", description = "更新订单的状态")
    @PutMapping("/{id}/status")
    public Result<Boolean> updateOrderStatus(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id,
            @Parameter(description = "订单状态", required = true) @RequestParam @NotNull Integer orderStatus) {
        
        boolean result = orderService.updateOrderStatus(id, orderStatus, LocalDateTime.now());
        if (result) {
            return Result.success(true, "状态更新成功");
        }
        return Result.error("状态更新失败");
    }

    @Operation(summary = "分配司机", description = "为订单分配司机")
    @PutMapping("/{id}/assign-driver")
    public Result<Boolean> assignDriver(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id,
            @Parameter(description = "司机ID", required = true) @RequestParam @NotNull Long driverId) {
        
        boolean result = orderService.assignDriver(id, driverId, LocalDateTime.now());
        if (result) {
            return Result.success(true, "司机分配成功");
        }
        return Result.error("司机分配失败");
    }

    @Operation(summary = "取消订单", description = "取消指定的订单")
    @PutMapping("/{id}/cancel")
    public Result<Boolean> cancelOrder(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id,
            @Parameter(description = "取消原因") @RequestParam(required = false) String cancelReason) {
        
        boolean result = orderService.cancelOrder(id, cancelReason, LocalDateTime.now());
        if (result) {
            return Result.success(true, "订单取消成功");
        }
        return Result.error("订单取消失败");
    }

    @Operation(summary = "完成订单", description = "完成指定的订单")
    @PutMapping("/{id}/complete")
    public Result<Boolean> completeOrder(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id) {
        
        boolean result = orderService.completeOrder(id, LocalDateTime.now());
        if (result) {
            return Result.success(true, "订单完成成功");
        }
        return Result.error("订单完成失败");
    }

    @Operation(summary = "统计订单数量", description = "根据条件统计订单数量")
    @GetMapping("/count")
    public Result<Long> countOrders(
            @Parameter(description = "订单状态") @RequestParam(required = false) Integer orderStatus,
            @Parameter(description = "用户ID") @RequestParam(required = false) Long userId,
            @Parameter(description = "司机ID") @RequestParam(required = false) Long driverId,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        Long count = orderService.countOrders(orderStatus, userId, driverId, startTime, endTime);
        return Result.success(count);
    }

    @Operation(summary = "获取订单统计数据", description = "获取订单的统计信息")
    @GetMapping("/statistics")
    public Result<List<Map<String, Object>>> getOrderStatistics(
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        List<Map<String, Object>> statistics = orderService.getOrderStatistics(startTime, endTime);
        return Result.success(statistics);
    }

    @Operation(summary = "获取用户订单列表", description = "获取指定用户的订单列表")
    @GetMapping("/user/{userId}")
    public Result<List<Order>> getUserOrders(
            @Parameter(description = "用户ID", required = true) @PathVariable @NotNull Long userId,
            @Parameter(description = "限制数量", example = "10") @RequestParam(defaultValue = "10") Integer limit) {
        
        List<Order> orders = orderService.getUserOrders(userId, limit);
        return Result.success(orders);
    }

    @Operation(summary = "获取司机订单列表", description = "获取指定司机的订单列表")
    @GetMapping("/driver/{driverId}")
    public Result<List<Order>> getDriverOrders(
            @Parameter(description = "司机ID", required = true) @PathVariable @NotNull Long driverId,
            @Parameter(description = "限制数量", example = "10") @RequestParam(defaultValue = "10") Integer limit) {
        
        List<Order> orders = orderService.getDriverOrders(driverId, limit);
        return Result.success(orders);
    }

    @Operation(summary = "获取待分配订单", description = "获取等待分配司机的订单列表")
    @GetMapping("/pending-assignment")
    public Result<List<Order>> getPendingAssignmentOrders(
            @Parameter(description = "限制数量", example = "10") @RequestParam(defaultValue = "10") Integer limit) {
        
        List<Order> orders = orderService.getPendingAssignmentOrders(limit);
        return Result.success(orders);
    }

    @Operation(summary = "获取进行中订单", description = "获取正在进行中的订单列表")
    @GetMapping("/in-progress")
    public Result<List<Order>> getInProgressOrders(
            @Parameter(description = "限制数量", example = "10") @RequestParam(defaultValue = "10") Integer limit) {
        
        List<Order> orders = orderService.getInProgressOrders(limit);
        return Result.success(orders);
    }

    @Operation(summary = "获取订单收入统计", description = "获取订单收入统计数据")
    @GetMapping("/income-stats")
    public Result<Map<String, Object>> getOrderIncomeStats(
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        Map<String, Object> stats = orderService.getOrderIncomeStats(startTime, endTime);
        return Result.success(stats);
    }

    @Operation(summary = "获取订单趋势数据", description = "获取订单趋势统计数据")
    @GetMapping("/trend")
    public Result<List<Map<String, Object>>> getOrderTrend(
            @Parameter(description = "天数", example = "7") @RequestParam(defaultValue = "7") Integer days) {
        
        List<Map<String, Object>> trend = orderService.getOrderTrend(days);
        return Result.success(trend);
    }

    @Operation(summary = "获取热门路线", description = "获取订单中的热门路线")
    @GetMapping("/popular-routes")
    public Result<List<Map<String, Object>>> getPopularRoutes(
            @Parameter(description = "限制数量", example = "10") @RequestParam(defaultValue = "10") Integer limit,
            @Parameter(description = "天数", example = "30") @RequestParam(defaultValue = "30") Integer days) {
        
        List<Map<String, Object>> routes = orderService.getPopularRoutes(limit, days);
        return Result.success(routes);
    }

    @Operation(summary = "批量更新订单状态", description = "批量更新多个订单的状态")
    @PutMapping("/batch-update-status")
    public Result<Boolean> batchUpdateOrderStatus(
            @Parameter(description = "订单ID列表", required = true) @RequestBody List<Long> orderIds,
            @Parameter(description = "订单状态", required = true) @RequestParam @NotNull Integer orderStatus) {
        
        boolean result = orderService.batchUpdateOrderStatus(orderIds, orderStatus, LocalDateTime.now());
        if (result) {
            return Result.success(true, "批量更新成功");
        }
        return Result.error("批量更新失败");
    }

    @Operation(summary = "更新订单费用", description = "更新订单的费用信息")
    @PutMapping("/{id}/fee")
    public Result<Boolean> updateOrderFee(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id,
            @Parameter(description = "订单费用", required = true) @RequestParam @NotNull java.math.BigDecimal orderFee) {
        
        boolean result = orderService.updateOrderFee(id, orderFee, LocalDateTime.now());
        if (result) {
            return Result.success(true, "费用更新成功");
        }
        return Result.error("费用更新失败");
    }

    @Operation(summary = "获取订单详细信息", description = "获取订单的详细信息包括关联数据")
    @GetMapping("/{id}/detail")
    public Result<Map<String, Object>> getOrderDetailInfo(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id) {
        
        Map<String, Object> detail = orderService.getOrderDetailInfo(id);
        if (detail == null || detail.isEmpty()) {
            return Result.error("订单详情不存在");
        }
        return Result.success(detail);
    }

    @Operation(summary = "智能分配司机", description = "根据算法智能为订单分配最合适的司机")
    @PutMapping("/{id}/smart-assign")
    public Result<Map<String, Object>> smartAssignDriver(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id) {
        
        Map<String, Object> result = orderService.smartAssignDriver(id);
        if (result != null && !result.isEmpty()) {
            return Result.success(result, "智能分配成功");
        }
        return Result.error("智能分配失败");
    }

    @Operation(summary = "预估订单费用", description = "根据起终点预估订单费用")
    @PostMapping("/estimate-fee")
    public Result<java.math.BigDecimal> estimateOrderFee(
            @Parameter(description = "起点纬度", required = true) @RequestParam @NotNull java.math.BigDecimal startLatitude,
            @Parameter(description = "起点经度", required = true) @RequestParam @NotNull java.math.BigDecimal startLongitude,
            @Parameter(description = "终点纬度", required = true) @RequestParam @NotNull java.math.BigDecimal endLatitude,
            @Parameter(description = "终点经度", required = true) @RequestParam @NotNull java.math.BigDecimal endLongitude,
            @Parameter(description = "服务类型") @RequestParam(required = false, defaultValue = "1") Integer serviceType) {
        
        java.math.BigDecimal fee = orderService.estimateOrderFee(startLatitude, startLongitude, endLatitude, endLongitude, serviceType);
        return Result.success(fee);
    }

    @Operation(summary = "获取订单评价", description = "获取订单的评价信息")
    @GetMapping("/{id}/rating")
    public Result<Map<String, Object>> getOrderRating(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id) {
        
        Map<String, Object> rating = orderService.getOrderRating(id);
        return Result.success(rating);
    }

    @Operation(summary = "订单评价", description = "对订单进行评价")
    @PostMapping("/{id}/rating")
    public Result<Boolean> rateOrder(
            @Parameter(description = "订单ID", required = true) @PathVariable @NotNull Long id,
            @Parameter(description = "评分", required = true) @RequestParam @NotNull java.math.BigDecimal rating,
            @Parameter(description = "评价内容") @RequestParam(required = false) String comment) {
        
        boolean result = orderService.rateOrder(id, rating, comment, LocalDateTime.now());
        if (result) {
            return Result.success(true, "评价成功");
        }
        return Result.error("评价失败");
    }

    @Operation(summary = "导出订单数据", description = "导出订单数据到Excel")
    @GetMapping("/export")
    public Result<List<Map<String, Object>>> exportOrderData(
            @Parameter(description = "订单ID列表") @RequestParam(required = false) List<Long> orderIds,
            @Parameter(description = "开始时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime) {
        
        List<Map<String, Object>> data = orderService.exportOrderData(orderIds, startTime, endTime);
        return Result.success(data);
    }

}